package com.example.gateway.filter;

import cn.hutool.core.util.StrUtil;
import com.copyctrl.campus.common.constant.HttpConstant;
import com.copyctrl.campus.common.constant.RedisConstant;
import com.copyctrl.campus.common.utils.StringUtils;
import com.example.gateway.config.IgnoreUrlsConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.concurrent.TimeUnit;

/**
 * @author:JH
 * @version:1.0
 *  刷新token存活时间 保证用户可以合法地向后端发送请求 每次请求都要去刷新，不管是否存在都放行。
 */
@Order(0)
@Component
@Slf4j
public class TokenFreshFilter implements GlobalFilter {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        // 0.获取请求参数
        ServerHttpRequest request = exchange.getRequest();
        // 1.获取请求头中的token
        String token = request.getHeaders().getFirst(HttpConstant.AUTHORIZATION);
        if (StrUtil.isBlank(token)) {
            return chain.filter(exchange);
        }
        // 2.基于TOKEN获取redis中的用户
        String key  = RedisConstant.TOKEN_KEY + token;
        String openid = stringRedisTemplate.opsForValue().get(key);
        log.info("AuthGlobalFilter.filter() redisKey:{} user:{}",key,openid);
        // 3.判断用户是否存在
        if (StrUtil.isEmpty(openid)) {
        // 4.不存在存在直接放行，说明token已经过期 无需进行刷新操作
            return chain.filter(exchange);
        }
        // 5.将查询到的hash数据转为JSON存入请求头中
        ServerHttpRequest request_new = exchange.getRequest().mutate().header(HttpConstant.USER, openid).build();
        exchange = exchange.mutate().request(request_new).build();
        // 6.刷新token有效期
        stringRedisTemplate.expire(key, RedisConstant.LOGIN_USER_TTL, TimeUnit.MINUTES);
        return chain.filter(exchange);
    }
}
